# -*- coding: utf-8 -*-

__author__ = 'bilibili'

import types
import threading
from spot_AM_Report_analyzer import spot_AM_Report_analyzer
from spot_TSL_analyzer import spot_TSL_analyzer
from spot_order_funnal_analyzer import spot_order_funnal_analyzer
from spot_prod_data_analyzer import spot_prod_data_analyzer
from spot_theater_BCPR_analyzer import spot_theater_BCPR_analyzer

class spot_data_manager:
    '''
    SINGLETON Region Begins
    '''
    instance = None  
    mutex = threading.Lock()

    def __new__(cls, *args, **kwd):  
        if spot_data_manager.instance is None:  
            spot_data_manager.instance = object.__new__(cls, *args, **kwd)
        return spot_data_manager.instance

    @staticmethod
    def get_instance():
        if spot_data_manager.instance == None:
            spot_data_manager.mutex.acquire()
            if spot_data_manager.instance == None:
                spot_data_manager.instance = spot_data_manager()
            spot_data_manager.mutex.release()         
        return spot_data_manager.instance
    '''
    SINGLETON Region Ends
    '''

    # FUNCTION: initialize(self, string)
    #   call this function when needs to load a new excel table
    # ARGS:
    #   @filenames: the new excel filename list
    def initialize(self, filenames):
        self.am_analyzer = spot_AM_Report_analyzer(filenames[0])
        self.am_analyzer.build_whole_table()

        self.tsl_analyzer = spot_TSL_analyzer(filenames[1])
        self.tsl_analyzer.build_whole_table()

        self.order_funnal_analyzer = spot_order_funnal_analyzer(filenames[2])
        self.order_funnal_analyzer.build_whole_table()

        self.prod_data_analyzer = spot_prod_data_analyzer(filenames[3])
        self.prod_data_analyzer.build_whole_table()

        self.bcpr_analyzer = spot_theater_BCPR_analyzer(filenames[4], filenames[5], filenames[6])
        self.bcpr_analyzer.initialize()

    # FUNCTION: tsl_theater_details(self, string, string)
    #   using the arguments to fetch the details stored in the tsl dict
    # ARGS:
    #   @theater_name: theater name
    #   @column_name: column name
    # RETURN:
    #   string: details
    def tsl_theater_details(self, theater_name, column_name):
        return self.tsl_analyzer.get_level_2_info(theater_name, column_name)

    # FUNCTION: attainment_details(self, string, string, string)
    #   statistics of the attainment data
    # ARGS:
    #   @year: the year
    #   @quarter: the quarter
    #   @theater: theater name
    # RETURN:
    #   dict: details about the attainment statistics
    def attainment_details(self, year, quarter, theater, title, top_cnt = 0):
        res = []
        titles = ['Coverage', 'Bookings Attainment', 'Revenue Attainment']
        quarter = 'Q' + quarter
        keys = [quarter + '_COVERAGE ' + quarter + '_COVERAGE_DESC', quarter + '_BOOKINGS_PM3_ATTAIN_PCT', quarter + '_REV_PM1_ATTAIN_PCT']
        attr_persist_1 = 'FY' + year[2: 4] + ' ' + quarter + ' Funnel - ' + quarter + ' Booking Date'
        for i in range(0, 3):
            dt = {}
            dt['id'] = i
            dt['title'] = titles[i]
            dt['subtitle'] = '%'
            if theater != '':
                dt['value'] = self.tsl_theater_details(theater, keys[i])
            if i == 0:
                attr1 = attr_persist_1
                attr2 = 'Booked & Commit Coverage'
            elif i == 1:
                attr1 = 'FY' + year[2:4] + ' YTD Bookings'
                attr2 = 'PM3 Attainment %'
            elif i == 2:
                attr1 = 'FY' + year[2:4] + ' YTD Revenue'
                attr2 = 'PM1 Attainment %'
            attain = self.am_analyzer.customized_calculation([attr_persist_1, attr1, attr2, theater])
            dt['pct'] = attain.length_info(True)
            if top_cnt > 0:
                attain = attain.the_top_ones(top_cnt)
                dt['detail'] = attain.detail_info(True, True)
            res.append(dt)
        if title == titles[0]:
            return res[0]
        elif title == titles[1]:
            return res[1]
        elif title == titles[2]:
            return res[2]
        return res

    def am_performance(self, year, quarter, theater, title, top_cnt = 0, index = -1):
        res = []
        titles = ['Coverage', 'Bookings Attainment', 'Revenue Attainment']
        quarter = 'Q' + quarter
        keys = [quarter + '_COVERAGE ' + quarter + '_COVERAGE_DESC', quarter + '_BOOKINGS_PM3_ATTAIN_PCT', quarter + '_REV_PM1_ATTAIN_PCT']
        attr_persist_1 = 'FY' + year[2: 4] + ' ' + quarter + ' Funnel - ' + quarter + ' Booking Date'
        for i in range(0, 3):
            if i == 0:
                attr1 = attr_persist_1
                attr2 = 'Booked & Commit Coverage'
            elif i == 1:
                attr1 = 'FY' + year[2:4] + ' YTD Bookings'
                attr2 = 'PM3 Attainment %'
            elif i == 2:
                attr1 = 'FY' + year[2:4] + ' YTD Revenue'
                attr2 = 'PM1 Attainment %'
            attain = self.am_analyzer.customized_calculation([attr_persist_1, attr1, attr2, theater])
            if top_cnt > 0:
                attain = attain.the_top_ones(top_cnt)
            tmp = attain.detail_info(True, True, index)[0]
            res.append(tmp)
        if title == titles[0]:
            return res[0]
        elif title == titles[1]:
            return res[1]
        elif title == titles[2]:
            return res[2]
        return res

    # FUNCTION: prod_data_details(self, string, string)
    #   statistics of the ProdData data
    # ARGS:
    #   @year: the year
    #   @quarter: the quarter
    # RETURN:
    #   dict: statistics of the ProdData data
    def prod_data_details(self, year, quarter, index_key = '', index_value = ''):
        arg_list = [year, quarter]
        if index_key != '':
            arg_list.append(index_key)
            arg_list.append(index_value)
        return self.prod_data_analyzer.customized_calculation(arg_list)

    # FUNCTION: prod_data_details(self)
    #   statistics of the ProdData data
    # RETURN:
    #   dict: order funnal table
    def order_funnal_details(self):
        return self.order_funnal_analyzer.get_result_dict()

    def bcpr_details(self, theater, year, quarter):
        bcpr = self.bcpr_analyzer
        ret_dict = []
        asl_attr_name = 'Q' + quarter + '_REV_YTD_PM1_ACTUAL'
        area_attr_name = 'Q' + quarter + '_BOOKED_COMMIT_AMT'
        for it in bcpr.plan_analyzer.get_result_dict()[theater]:
            tmp_dict = {}
            tmp_dict['TheaterName'] = theater
            tmp_dict['AreaName'] = it['Area']
            tmp_dict['Data'] = {}
            tmp_dict['Data']['Plan Value SO'] = it[year + '.' + quarter]['Plan Value SO']
            flag = True
            key = theater + '~' + it['Area']
            if bcpr.asl_analyzer.get_result_dict().has_key(key):
                tmp_dict['Data'][asl_attr_name] = bcpr.asl_analyzer.get_result_dict()[key][asl_attr_name]
            else:
                flag = False
            if bcpr.area_analyzer.get_result_dict().has_key(key):
                tmp_dict['Data'][area_attr_name] = bcpr.area_analyzer.get_result_dict()[key][area_attr_name]
            else:
                flag = False
            if flag: 
                ret_dict.append(tmp_dict)
        return ret_dict
